import CodeMirror from 'codemirror'
import { getFormulaFunNameList } from './FormulaList'

function parseWords() {
  let obj = {}
  let keywordsList = getFormulaFunNameList()
  for (let i = 0; i < keywordsList.length; ++i) obj[keywordsList[i]] = true
  return obj
}

// 关键字
let keywords = parseWords()

CodeMirror.defineMode('formula', function (config, parserConfig) {
  let type, content

  function ret(tp, style, cont) {
    type = tp
    content = cont
    return style
  }

  function tokenBase(stream, state) {
    state.beforeParams = false
    let ch = stream.next()
    if (ch == '.' && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) {
      return ret('number', 'number')
    } else if (ch == '[') {
      stream.skipTo(']')
      stream.eat(']')
      return ret('string', 'string')
    } else if (/\d/.test(ch)) {
      stream.eatWhile(/[\w\.]/)
      return 'number'
    } else if (['+', '-', '*', '/'].indexOf(ch) > -1) {
      return 'atom'
    } else {
      stream.eatWhile(/[\w\$_{}\xa1-\uffff]/)
      let word = stream.current()
      if (keywords && keywords.propertyIsEnumerable(word)) {
        state.beforeParams = true
        return 'keyword'
      }
      return null
    }
  }

  return {
    startState: function () {
      return {
        tokenize: tokenBase,
        beforeParams: false,
        inParams: false
      }
    },
    token: function (stream, state) {
      if (stream.eatSpace()) return null
      return state.tokenize(stream, state)
    }
  }
})
// 自动补全提示
CodeMirror.registerHelper('hint', 'formula', function (cm) {
  let hintList = getFormulaFunNameList()
  let cur = cm.getCursor(),
    token = cm.getTokenAt(cur)
  let start = token.start,
    end = cur.ch
  let str = token.string

  let list = hintList.filter(function (item) {
    return item.indexOf(str) === 0
  })

  if (list.length)
    return {
      list: list,
      from: CodeMirror.Pos(cur.line, start),
      to: CodeMirror.Pos(cur.line, end)
    }
})

CodeMirror.defineMIME('text/x-formula', 'formula')

export default CodeMirror
